package com.zkyc.framework.website.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zkyc.framework.common.constant.NumberConstant;
import com.zkyc.framework.common.exception.ResultCode;
import com.zkyc.framework.common.mapper.FileMapper;
import com.zkyc.framework.common.mapper.MediaTagMapper;
import com.zkyc.framework.common.pojo.*;
import com.zkyc.framework.common.utils.WebsiteUtil;
import com.zkyc.framework.common.vo.ResultVO;
import com.zkyc.framework.common.vo.website.FileDownloadCountVo;
import com.zkyc.framework.common.vo.website.Media;
import com.zkyc.framework.common.vo.website.MediaVo;
import com.zkyc.framework.website.client.RoleClient;
import com.zkyc.framework.website.mapper.MediaMapper;
import com.zkyc.framework.website.mapper.SystemFileRefSubjectMapper;
import com.zkyc.framework.website.mapper.SystemFileRefTagMapper;
import com.zkyc.framework.website.service.MediaService;
import com.zkyc.framework.website.util.TokenUserUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class MediaServiceImpl implements MediaService {

    @Autowired
    FileMapper fileMapper;

    @Autowired
    MediaMapper mediaMapper;

    @Autowired
    MediaTagMapper mediaTagMapper;

    @Autowired
    SystemFileRefTagMapper systemFileRefTagMapper;

    @Autowired
    SystemFileRefSubjectMapper systemFileRefSubjectMapper;

    @Autowired
    RoleClient roleClient;

    @Override
    public Media queryById(Integer id) {
        Media media = mediaMapper.queryMediaById(id);
        return media;
    }


    @Override
    public ResultVO queryList(MediaVo media) {
        List<Media> mediaList;
        String websiteId = WebsiteUtil.getWebsiteId();
        if (StringPool.ZERO.equals(media.getBelongKey())) {
            Integer tagId = null;
            if (media.getTagId() != null && media.getTagId().size() > 0) {
                List<Integer> tagIdList = media.getTagId().get(0);
                tagId = tagIdList.get(1);
            }
            if (StringPool.ONE.equals(media.getIsContent())) {
                mediaList = mediaMapper.queryList(media.getType(), media.getSubjectId(), tagId,
                        media.getDescription(), media.getCreateTime(), media.getBelongKey(), websiteId, media.getBeginDate(), media.getEndDate(), media.getDateType(), media.getIsContent());
            } else {
                String userId = TokenUserUtil.getCurrentUserId();
                String dataRight = roleClient.getDataRight(websiteId, userId);
                if (StringPool.ONE.equals(dataRight)) userId = null;
                mediaList = mediaMapper.queryMediaList(media.getType(), media.getSubjectId(), tagId,
                        media.getDescription(), media.getCreateTime(), media.getBelongKey(), websiteId, media.getBeginDate(), media.getEndDate(), media.getDateType(),userId);
            }
            if (StringPool.ONE.equals(media.getIsContent())) {
                for (int i = 0; i < mediaList.size(); i++) {
                    Media media1 = mediaList.get(i);
                    String mediaTagName = media1.getMediaTagName();
                    String contentTitle = media1.getContentTitle();
                    if (i > 0
                            && (!mediaTagName.equals(mediaList.get(i - 1).getMediaTagName()))
                            && !" ".equals(mediaList.get(i - 1).getMediaTagName())
                            && (contentTitle.equals(mediaList.get(i - 1).getContentTitle()))) {
                        mediaList.get(i - 1).setMediaTagName(mediaList.get(i - 1).getMediaTagName() + "," + mediaTagName);
                        mediaList.remove(media1);
                        --i;
                    }
                }
                HashSet<String> hashSet = new HashSet<>();
                for (int i = 0; i < mediaList.size(); i++) {
                    Media media1 = mediaList.get(i);
                    String contentTitle = media1.getContentTitle();
                    if (hashSet.contains(contentTitle)){
                        mediaList.remove(media1);
                        --i;
                    }
                    hashSet.add(contentTitle);
                }
            } else {
                HashSet<Long> hashSetId = new HashSet<>();
                for (int i = 0; i < mediaList.size(); i++) {
                    Media media1 = mediaList.get(i);
                    Long id = media1.getId();
                    if (hashSetId.contains(id)) {
                        String mediaTagName = media1.getMediaTagName();
                        if ((!mediaTagName.equals(mediaList.get(i - 1).getMediaTagName())) && !" ".equals(mediaList.get(i - 1).getMediaTagName())) {
                            mediaList.get(i - 1).setMediaTagName(mediaList.get(i - 1).getMediaTagName() + "," + mediaTagName);
                        }
                        mediaList.remove(media1);
                        --i;
                    }
                    hashSetId.add(id);
                }
            }
            for (Media media1 : mediaList) {
                if (media1.getDownloadCount() == null) {
                    media1.setDownloadCount(NumberConstant.NUMBER_0);
                }
                List tagLists = new LinkedList();
                List tagNames = new LinkedList();
                Long fileId = media1.getId();
                List<Integer> tagIdList = mediaMapper.queryTagIdList(fileId);
                for (Integer tagRefId : tagIdList) {
                    List list = new LinkedList();
                    JSONObject jsonObject = mediaMapper.queryTagByTagId(tagRefId);
                    if (jsonObject != null) {
                        if (jsonObject.get("tag_group_id") == null) {
                            continue;
                        }
                        list.add(jsonObject.get("tag_group_id"));
                        list.add(jsonObject.get("id"));
                        tagLists.add(list);
                        tagNames.add(jsonObject.get("media_tag_name"));
                    }
                }
                media1.setTagId(tagLists);
                media1.setTagNames(tagNames);
            }
        } else {
            mediaList = mediaMapper.queryOtherFile(websiteId, media.getType(), media.getBeginDate(), media.getEndDate());
        }
        return ResultVO.data(getPages(media.getCurrent(), media.getSize(), mediaList));
    }

    @Override
    public ResultVO insert(MediaVo mediaVo) {
        String[] ids = mediaVo.getId().split(",");
        for (String id : ids) {
            File file = fileMapper.selectById(id);
            if (file != null) {
                file.setCreateTime(new Date());
                file.setUpdateTime(new Date());
                BeanUtils.copyProperties(mediaVo, file);
                String websiteId = WebsiteUtil.getWebsiteId();
                file.setWebsiteId(websiteId);
                fileMapper.updateById(file);
                insertRef(mediaVo, id);
            }
        }
        return ResultVO.success(ResultCode.SUCCESS);
    }


    @Override
    public ResultVO update(MediaVo mediaVo) {
        String id = mediaVo.getId();
        File file = fileMapper.selectById(id);
        file.setUpdateTime(new Date());
        BeanUtils.copyProperties(mediaVo, file);
        String websiteId = WebsiteUtil.getWebsiteId();
        file.setWebsiteId(websiteId);
        fileMapper.updateById(file);
        systemFileRefTagMapper.delete(Long.parseLong(id));
        systemFileRefSubjectMapper.delete(Long.parseLong(id));
        insertRef(mediaVo, id);
        return ResultVO.success(ResultCode.SUCCESS);
    }

    @Override
    public ResultVO dowanloadCount(String id) {
        countInc(id);
        return ResultVO.success(ResultCode.SUCCESS);
    }

    @Override
    public ResultVO queryByType(Integer current, Integer size, String type) {
        Page page = new Page(current, size);
        String websiteId = WebsiteUtil.getWebsiteId();
        QueryWrapper<File> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("type", type);
        queryWrapper.eq("website_id", websiteId);
        queryWrapper.eq("belong_key", NumberConstant.NUMBER_0);
        return ResultVO.data(fileMapper.selectPage(page, queryWrapper));
    }

    @Override
    public List<FileDownloadCountVo> selectByIds(List<Long> ids) {
        List<File> files = fileMapper.selectBatchIds(ids);
        List<FileDownloadCountVo> fileDownloadCountVos = new ArrayList<>();
        for (File file : files) {
            FileDownloadCountVo fileDownloadCountVo = new FileDownloadCountVo();
            BeanUtils.copyProperties(file,fileDownloadCountVo);
            if (fileDownloadCountVo.getDownloadCount() == null){
                fileDownloadCountVo.setDownloadCount(0);
            }
            fileDownloadCountVos.add(fileDownloadCountVo);
        }
        return fileDownloadCountVos;
    }

    @Async
    void countInc(String id) {
        int count;
        File file = fileMapper.selectById(id);
        if (file.getDownloadCount() == null) {
            count = 1;
        } else {
            count = file.getDownloadCount() + 1;
        }
        if (file != null) {
            file.setDownloadCount(count);
            fileMapper.updateById(file);
        }
    }

    private void insertRef(MediaVo mediaVo, String id) {
        String subjectId = mediaVo.getSubjectId() + "";
        if (StringUtils.isNotBlank(subjectId)) {
            SystemFileRefSubject fileRefSubject = new SystemFileRefSubject();
            fileRefSubject.setFileId(Long.parseLong(id));
            fileRefSubject.setMediaTagId(Integer.parseInt(mediaVo.getSubjectId()));
            systemFileRefSubjectMapper.insert(fileRefSubject);
        }
        SystemFileRefTag fileRefTag = new SystemFileRefTag();
        if (mediaVo.getTagId() != null && mediaVo.getTagId().size() > 0) {
            List<List<Integer>> tagIdList = mediaVo.getTagId();
            for (List<Integer> integers : tagIdList) {
                fileRefTag.setFileId(Long.parseLong(id));
                fileRefTag.setMediaTagId(integers.get(integers.size() - 1));
                systemFileRefTagMapper.insert(fileRefTag);
            }
        } else {
            if (mediaMapper.queryNullTag() == null) {
                MediaTag mediaTag = new MediaTag();
                mediaTag.setId(NumberConstant.NUMBER_0);
                mediaTag.setMediaTagName(" ");
                mediaTagMapper.insert(mediaTag);
            }
            int tagId = mediaTagMapper.selectZero();
            fileRefTag.setFileId(Long.parseLong(id));
            fileRefTag.setMediaTagId(tagId);
            systemFileRefTagMapper.insert(fileRefTag);
        }
    }

    /**
     * 分页函数
     *
     * @param currentPage 当前页数
     * @param pageSize    每一页的数据条数
     * @param list        要进行分页的数据列表
     * @return 当前页要展示的数据
     * @author pochettino
     */
    private Page getPages(Integer currentPage, Integer pageSize, List list) {
        if (currentPage == null) {
            currentPage = 1;
        }
        if (pageSize == null) {
            pageSize = 10;
        }
        Page page = new Page();
        if (list == null) {
            return null;
        }
        int size = list.size();

        if (pageSize > size) {
            pageSize = size;
        }
        if (pageSize != 0) {
            // 求出最大页数，防止currentPage越界
            int maxPage = size % pageSize == 0 ? size / pageSize : size / pageSize + 1;

            if (currentPage > maxPage) {
                currentPage = maxPage;
            }
        }
        // 当前页第一条数据的下标
        int curIdx = currentPage > 1 ? (currentPage - 1) * pageSize : 0;

        List pageList = new ArrayList();

        // 将当前页的数据放进pageList
        for (int i = 0; i < pageSize && curIdx + i < size; i++) {
            pageList.add(list.get(curIdx + i));
        }

        page.setCurrent(currentPage).setSize(pageSize).setTotal(list.size()).setRecords(pageList);
        return page;
    }

}
